import { HttpResponse } from '@angular/common/http';
import { Injectable, Injector } from '@angular/core';
import { AbstractApiUrlDataService } from '@basic/abstracts';
import { DA_SERVICE_TOKEN, JWTTokenModel } from '@delon/auth';
import { _HttpClient } from '@delon/theme';
import { FileSaverOptions, saveAs } from 'file-saver';
import { NzMessageService } from 'ng-zorro-antd/message';

export const ErrorCode: any = {
    '401': '认证失败，无法访问系统资源',
    '403': '当前操作没有权限',
    '404': '访问资源不存在',
    default: '系统未知错误，请反馈给管理员'
};

@Injectable({ providedIn: 'root' })
export class FileSaveService {
    constructor(
        private msg: NzMessageService,
        private injector: Injector,
        private apiUrl: AbstractApiUrlDataService,
        private http: _HttpClient
    ) {}

    getToken() {
        const model = this.injector.get(DA_SERVICE_TOKEN).get<JWTTokenModel>(JWTTokenModel);
        return model.token;
    }

    blobValidate(data: any) {
        return data.type !== 'application/json';
    }

    getResponseHeaders(res: HttpResponse<Blob>, resHeader: string) {
        const keys = res.headers.keys(); // 获取响应头各参数名数组
        const headers = keys.map(key => `${key.toLowerCase()}:${res.headers.get(key)}`); // 获取响应头各参数名及参数值的数组
        let resHeaderContent = '';
        if (resHeader && headers && headers.length) {
            headers.forEach(head => {
                if (head.indexOf(resHeader) != -1) {
                    resHeaderContent = head.split(':')[1];
                }
            });
        }
        return resHeaderContent;
    }
    oss(ossId: string) {
        var url = `${this.apiUrl.baseUrl}/resource/oss/download/${ossId}`;
        this.http
            .request('get', url, {
                responseType: 'blob',
                observe: 'response',
                headers: { Authorization: `Bearer ${this.getToken()}` }
            })
            .subscribe({
                next: res => {
                    const isBlob = this.blobValidate(res.body);
                    if (isBlob) {
                        const blob = new Blob([res.body!], { type: 'application/octet-stream' });
                        this.saveAs(blob, decodeURIComponent(this.getResponseHeaders(res, 'download-filename')));
                    } else {
                        this.printErrMsg(res.body);
                    }
                },
                error: err => {
                    console.error(err);
                    this.msg.error('下载文件出现错误，请联系管理员！');
                }
            });
    }
    zip(url: string, name: string) {
        const _url = this.apiUrl.baseUrl + url;
        this.http
            .request('get', _url, {
                responseType: 'blob',
                observe: 'response',
                headers: {
                    Authorization: `Bearer ${this.getToken()}`,
                    datasource: localStorage.getItem('dataName') ?? ''
                }
            })
            .subscribe({
                next: res => {
                    const isBlob = this.blobValidate(res.body);
                    if (isBlob) {
                        const blob = new Blob([res.body!], { type: 'application/zip' });
                        this.saveAs(blob, name);
                    } else {
                        this.printErrMsg(res.body);
                    }
                },
                error: err => {
                    console.error(err);
                    this.msg.error('下载文件出现错误，请联系管理员！');
                }
            });
    }
    saveAs(data: Blob | string, filename?: string, options?: FileSaverOptions) {
        saveAs(data, filename, options);
    }

    async printErrMsg(data: any) {
        const resText = await data.text();
        const rspObj: any = JSON.parse(resText);
        const errMsg = ErrorCode[rspObj.code] || rspObj.msg || ErrorCode['default'];
        this.msg.error(errMsg);
    }
}
